import datetime
import time
from typing import List

from shapely import Point
from shapely.geometry import Polygon

from config.database import SessionLocal
from core.dao.cms_alert_message_dao import CmsAlertMessageDao
from core.dao.cms_gaode_fence_terminal_dao import CmsGaodeFenceTerminalDao
from core.dao.cms_gaode_trace_dao import CmsGaodeTraceDao
from core.dao.cms_gaode_trace_day_dao import CmsGaodeTraceDayDao
from core.dao.cms_terminal_point_dao import CmsTerminalPointDao
from core.entity.do.models import CmsGaodeFenceTerminal
from core.entity.vo.view_models import CarModelForAll, CmsAlertMessageVO, CarModelForAllTrack, CmsCarTrackVO, \
    CmsGaodeTraceVO
from core.service.cms_alert_message_service import CmsAlertMessageService
from core.service.cms_car_service import CmsCarService
from core.service.cms_car_track_service import CmsCarTrackService
from core.service.gaode.gaode_dili_service import GaodeDiLiService
from core.service.gaode.gaode_fence_terminal_service import GaodeFenceTerminalService
from core.service.gaode.gaode_trace_service import GaodeTraceService
from models import CmsGaodeTrace, CmsGaodeTraceDay
from utils.uuid import UUID


class AlertMessageService:
    @classmethod
    def add_message(cls):
        db = SessionLocal()
        print("被调用了")
        # 查询出所有车辆集合
        try:
            uuid = UUID()
            list_all_car_running: List[CarModelForAll] = CmsCarService.get_cms_car_list_all(db)
            for e in list_all_car_running:
                # 查询车辆当前经纬度
                if e.device_id is None:
                    continue
                terminal_point = CmsTerminalPointDao.get_cms_terminal_point_by_terminal_id_last_one(db, e.device_id)
                if terminal_point is None or terminal_point.lon is None or terminal_point.lat is None:
                    continue
                if e.polygon_points:
                    # 将字符串解析为点坐标列表
                    points = []
                    try:
                        # 分割字符串为经纬度对列表
                        pairs = e.polygon_points.split(';')[:-1]  # 移除尾部的空字符串（如果有的话）
                        for pair in pairs:
                            # 尝试将每对经纬度分割为两个值
                            lon_lat = pair.split(',')
                            if len(lon_lat) == 2:  # 确保每对只有一个逗号
                                lon, lat = float(lon_lat[0]), float(lon_lat[1])
                                points.append((lon, lat))
                            else:
                                print(f"Invalid pair: {pair}")  # 打印无效的对以进行调试
                    except ValueError as e:
                        print(f"Error converting values: {e}")
                    points.append(points[0])
                    polygon = Polygon(points)
                    test_point_polygon = Point((terminal_point.lon, terminal_point.lat))
                    # 检查点是否在多边形内
                    if test_point_polygon.within(polygon):
                        in_ = 1
                    else:
                        in_ = 0
                    cls.alter_message(db, e, in_, terminal_point, uuid)
                    # cls.gaode_fence(db, e, terminal_point, uuid)
            db.commit()
        except Exception as e:
            db.rollback()
            raise ValueError(e)
        finally:
            db.close()

    @classmethod
    def alter_message(cls, db, e, in_, terminal_point, uuid):
        ter: CmsGaodeFenceTerminal = CmsGaodeFenceTerminalDao.get_cms_gaode_fence_terminal_by_fence_id_and_ter(
            db, e.fence_id, e.car_id)
        vo = CmsAlertMessageVO()
        vo.id = int(uuid.uuid())
        vo.fence_id = e.fence_id
        vo.fence_name = e.fence_name
        vo.car_id = e.car_id
        vo.car_number = e.car_number
        vo.state = 1
        if ter and e.alarm_type == '进入监控' and ter.update_by == '0' and in_ == 1:
            vo.alert_type = '进入监控'
            vo.alert_msg = '进入监控'
            cls.method_name(terminal_point, vo)
            CmsAlertMessageDao.add_cms_alert_message_dao(db, vo)
        if ter and e.alarm_type == '离开监控' and ter.update_by == '1' and in_ == 0:
            vo.alert_type = '离开监控'
            vo.alert_msg = '离开监控'
            # 查询当前位置
            cls.method_name(terminal_point, vo)
            CmsAlertMessageService.add_cms_alert_message(db, vo)

    # @classmethod
    # def gaode_fence(cls, db, e, terminal_point, uuid):
    #     status = GaodeFenceTerminalService.query_fence_location_status("1033614",
    #                                                                    str(terminal_point.lon) + "," +
    #                                                                    str(terminal_point.lat),
    #                                                                    e.fence_id)
    #     if 'errcode' in status and status['errcode'] == 10000:
    #         ter: CmsGaodeFenceTerminal = CmsGaodeFenceTerminalDao.get_cms_gaode_fence_terminal_by_fence_id_and_ter(
    #             db, e.fence_id, e.car_id)
    #         in_ = status['data']['results'][0]['in']
    #         vo = CmsAlertMessageVO()
    #         vo.id = int(uuid.uuid())
    #         vo.fence_id = e.fence_id
    #         vo.fence_name = e.fence_name
    #         vo.car_id = e.car_id
    #         vo.car_number = e.car_number
    #         vo.state = 1
    #         if ter and e.alarm_type == '进入监控' and ter.update_by == '0' and in_ == 1:
    #             vo.alert_type = '进入监控'
    #             vo.alert_msg = '进入监控'
    #             cls.method_name(terminal_point, vo)
    #             CmsAlertMessageDao.add_cms_alert_message_dao(db, vo)
    #         if ter and e.alarm_type == '离开监控' and ter.update_by == '1' and in_ == 0:
    #             vo.alert_type = '离开监控'
    #             vo.alert_msg = '离开监控'
    #             # 查询当前位置
    #             cls.method_name(terminal_point, vo)
    #             CmsAlertMessageService.add_cms_alert_message(db, vo)
    #         if ter and status['data']['results'][0]['in'] is not None:
    #             ter.update_by = status['data']['results'][0]['in']
    #             CmsGaodeFenceTerminalDao.add_cms_gaode_fence_terminal(db, ter)

    @classmethod
    def method_name(cls, terminal_point, vo):
        # 查询当前位置
        address = GaodeDiLiService.get_address(terminal_point['lon'] + "," + terminal_point['lat'])
        if 'status' in address and address['status'] == '1':
            component_ = address['regeocode']['addressComponent']
            list = []
            address = ""
            i = 0
            list.append(component_['country'])
            list.append(component_['province'])
            list.append(component_['city'])
            list.append(component_['township'])
            for location in list:
                if location is not None and len(location) != 0:
                    address = address + location
                    i = i + 1
                    if i != len(list):
                        address = address + ","
            vo.location = address

    # @classmethod
    # def upload_point(cls):
    #     db = SessionLocal()
    #     print(f"{datetime.datetime.now()}upload_point被调用了")
    #     # 查询出所有车辆集合
    #     try:
    #         uuid = UUID()
    #         list_all_car_running: List[CarModelForAllTrack] = CmsCarService.get_cms_car_list_all_track(db)
    #         for e in list_all_car_running:
    #             # 上传轨迹
    #             track_vo = CmsCarTrackVO(**e.__dict__)
    #             uuid_uuid = uuid.uuid()
    #             track_vo.id = uuid_uuid
    #             track_vo.record_time = datetime.datetime.now()
    #             track_vo.track_id = "tra_" + uuid_uuid
    #             track_vo.gaode_track_id = None
    #             track_vo.track_name = track_vo.track_id
    #             track_vo.state = 1
    #             CmsCarTrackService.add_cms_car_track(db, track_vo)
    #         db.commit()
    #     except Exception as e:
    #         db.rollback()
    #         raise ValueError(e)
    #     finally:
    #         db.close()

    # @classmethod
    # def query_all_extence(cls):
    #     db = SessionLocal()
    #     print(f"{datetime.datetime.now()}query_all_extence被调用了")
    #     try:
    #         uuid = UUID()
    #         running: List[CmsGaodeTrace] = CmsGaodeTraceDao.get_cms_gaode_trace_running(db)
    #         for e in running:
    #             day = CmsGaodeTraceVO(**e.__dict__)
    #             track = GaodeTraceService.search_track(e.service_id, e.terminal_id,
    #                                                    e.execute_id)
    #             if track['errcode'] == 10000 and 'data' in track and track['data']['counts'] > 0:
    #                 distance_ = track['data']['tracks'][0]['distance']
    #                 time1 = track['data']['tracks'][0]['time']
    #                 old_day: List[CmsGaodeTraceDay] = CmsGaodeTraceDayDao.get_cms_gaode_trace_day_by_execute_id(db,
    #                                                                                                             e.execute_id)
    #                 old_distance_ = 0
    #                 old_time = 0
    #                 if old_day and len(old_day) > 0:
    #                     for e_day in old_day:
    #                         old_distance_ = old_distance_ + e_day.distance
    #                         old_time = old_time + e_day.time
    #                 day.id = uuid.uuid()
    #                 day.create_time = None
    #                 day.update_time = None
    #                 day.distance = distance_ - old_distance_
    #                 day.time = time1 - old_time
    #                 now = datetime.datetime.now()
    #                 start_time = now.replace(hour=3, minute=30, second=0, microsecond=0)
    #                 end_time = now.replace(hour=4, minute=0, second=0, microsecond=0)
    #                 have_day = CmsGaodeTraceDayDao.get_cms_gaode_trace_day_by_execute_id_and_time(db, e.execute_id)
    #                 if not have_day and start_time <= now <= end_time:
    #                     CmsGaodeTraceDayDao.add_cms_gaode_trace_day_dao(db, day)
    #                     db.commit()
    #         db.commit()
    #     except Exception as e:
    #         db.rollback()
    #         raise ValueError(e)
    #     finally:
    #         db.close()
